package it.koutifaris.travianmap.mapsqlparser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.util.Log;

public class MapSqlParser {

	protected final String TAG = this.getClass().getName();

	private static final String PARSING_REGEX = "(-?\\d+)|'(.*?)(?<!')'|'(.*?(?:'')+)'|'()'";
	private static final Pattern PATTERN = Pattern.compile(PARSING_REGEX);

	private EntryBuilder entryBuilder = new EntryBuilder();

	public void parse(InputStream sourceStream, MapSqlEntryHandler handler) throws IOException, SqlParserException {

		BufferedReader bufferedReader = new BufferedReader(
				new InputStreamReader(sourceStream, Charset.forName("UTF-8")));
		String line;

		long readLineTime = 0;
		long startMillis = System.currentTimeMillis();

		long parseTime = 0;

		while ((line = bufferedReader.readLine()) != null) {
			readLineTime += System.currentTimeMillis() - startMillis;

			long startParse = System.currentTimeMillis();
			MapSqlEntry entry = parseLine(line);
			parseTime += System.currentTimeMillis() - startParse;

			boolean stop = !handler.onEntry(entry);
			if (stop) {
				break;
			}

			startMillis = System.currentTimeMillis();
		}

		Log.i(TAG, "readLineTime: " + readLineTime);
		Log.i(TAG, "parseTime: " + parseTime);
	}

	protected MapSqlEntry parseLine(String line) throws SqlParserException {
		try {
			Matcher matcher = PATTERN.matcher(line);
			entryBuilder.clear();
			while (matcher.find()) {
				if (matcher.groupCount() != 4) {
					throw new Exception("Unexpected group count: " + matcher.groupCount());
				}

				String value = null;
				for (int i = 1; i <= matcher.groupCount(); i++) {
					value = matcher.group(i);
					if (value != null) {
						break;
					}
				}

				entryBuilder.addValue(value);
			}

			return entryBuilder.build();
		} catch (Exception e) {
			throw new SqlParserException("Error while parsing " + line, e);
		}
	}

	// public static void main(String[] args) {
	// String expression =
	// "INSERT INTO `x_world` VALUES (472992,1,-190,2,120913,'08 scipione',89178,'bitta&gratta',1386,'BlAs\\'FeMi',83);";
	// Pattern pattern = Pattern.compile("(-?\\d+|'.*?[^(?:\\\\')]')");
	//
	// System.out.println(expression);
	// System.out.println();
	// Matcher matcher = pattern.matcher(expression);
	// while (matcher.find()) {
	// int groupCount = matcher.groupCount();
	// for (int i = 1; i <= groupCount; i++) {
	// System.out.print("#" + matcher.group(i) + "#");
	// }
	// System.out.println();
	// }
	// }
}
